package com.ray.test.hander;

import com.alibaba.fastjson.JSON;
import com.ray.test.actuator.params.ParamsBuilder;
import com.ray.test.core.CoreUtil;
import com.ray.test.proxy.MockTestConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.List;

/**
 * @author bo shen
 * @Description: spring 事务 处理
 * @Class: SpringTxHander
 * @Package com.ray.test.hander
 * @date 2019/12/12 15:14
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
public class MockHander {
    /***上下文容器**/
    private MockHanderContent mockHanderContent;

    public MockHander(MockHanderContent mockHanderContent) {
        this.mockHanderContent = mockHanderContent;
    }

    public int runTest() {
        MockTestConfig.clearConfig();
        if (mockHanderContent == null || mockHanderContent.getRunClasss() == null) {
            log.info("单元测试执行结束，参数不合法");
            return 0;
        }
        log.info("单元测试类:{}执行开始", mockHanderContent.getRunClasss().getName());
        Integer success = 0;
        Integer error = 0;
        Method[] methods = mockHanderContent.getRunClasss().getDeclaredMethods();
        for (Method method : methods) {
            //只有公有方法才能被执行
            if(!Modifier.isPublic(method.getModifiers())){
                continue;
            }
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            //排除方法
            if (CoreUtil.isPass(method.getName(), mockHanderContent.getRunClasss(), mockHanderContent.getIncludeMethodName(), mockHanderContent.getExcludeMethodName())) {
                continue;
            }

            //构建参数
            Parameter[] parameters = method.getParameters();
            List<Object> params = ParamsBuilder.getInstance().bulider(parameters, method, null);
            log.info("方法参数数量{}:,单元测试-执行参数:{}", parameters.length,JSON.toJSONString(params));
            //方法执行
            try {
                log.info("接口[{}]执行参数:{}", mockHanderContent.getRunTarget().getClass().getName(),JSON.toJSONString(params));
                method.invoke(mockHanderContent.getRunTarget(), params.toArray());
                success ++;
            } catch (Exception e) {
                error ++;
                log.info("当前执行类:[{}]-方法[{}]的单元测试-失败", mockHanderContent.getRunClasss(), method.getName(), e);
            }
            stopWatch.stop();
            log.info("当前执行类:[{}]-方法[{}]的单元测试-成功，耗时:{}", mockHanderContent.getRunClasss(), method.getName(), stopWatch.getTotalTimeMillis());
        }
        log.info("单元测试执行结果，成功:{},失败:{}", success, error);
        return error;
    }
}
